home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / infosrvr / dev / www_talk.930 / 000324_connolly@pixel.convex.com _Tue Nov 17 03:21:23 1992.msg < prev    next >
Internet Message Format  |  1994-01-24  |  11KB

  1. Return-Path: <connolly@pixel.convex.com>
  2. Received: from dxmint.cern.ch by  nxoc01.cern.ch  (NeXT-1.0 (From Sendmail 5.52)/NeXT-2.0)
  3.     id AA29448; Tue, 17 Nov 92 03:21:23 MET
  4. Received: by dxmint.cern.ch (dxcern) (5.57/3.14)
  5.     id AA05521; Tue, 17 Nov 92 03:34:19 +0100
  6. Received: from pixel.convex.com by convex.convex.com (5.64/1.35)
  7.     id AA08673; Mon, 16 Nov 92 20:33:15 -0600
  8. Received: from localhost by pixel.convex.com (5.64/1.28)
  9.     id AA17244; Mon, 16 Nov 92 20:33:08 -0600
  10. Message-Id: <9211170233.AA17244@pixel.convex.com>
  11. To: marca@ncsa.uiuc.edu (Marc Andreessen)
  12. Cc: www-talk@nxoc01.cern.ch
  13. Subject: Re: html & emacs 
  14. In-Reply-To: Your message of "Mon, 16 Nov 92 20:21:23 PST."
  15.              <9211170421.AA03160@wintermute.ncsa.uiuc.edu> 
  16. Mime-Version: 1.0
  17. Content-Type: multipart/mixed; boundary="cut-here"
  18. Date: Mon, 16 Nov 92 20:33:08 CST
  19. From: Dan Connolly <connolly@pixel.convex.com>
  20.  
  21.  
  22. --cut-here
  23.  
  24. >Anyone written code to construct HTML files in Emacs?  I'm hacking
  25. >something up; let me know if you're interested....
  26.  
  27. I use sgml-mode to verify HTML documents and WWW to see how
  28. they format. So every once in a while I do C-c C-v to call
  29. the sgml parser and verify the document, and I use compile
  30. mode to run www and "preview" the document.
  31.  
  32. If you come up with something more WYSIWIG, I'd like to
  33. see it.
  34.  
  35. Dan
  36.  
  37. --cut-here
  38. Content-Description: SGML mode by James Clark (jjc@jclark.com)
  39. Content-Type: application/octet-stream; type="elisp"
  40.  
  41. ;; SGML mode.
  42. ;; Copyright (C) 1992 James Clark (jjc@jclark.com)
  43. ;; Parts derived from blink-matching-open in simple.el, which is
  44. ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
  45.  
  46. ;; This file is not yet part of GNU Emacs.
  47.  
  48. ;; GNU Emacs is free software; you can redistribute it and/or modify
  49. ;; it under the terms of the GNU General Public License as published by
  50. ;; the Free Software Foundation; either version 1, or (at your option)
  51. ;; any later version.
  52.  
  53. ;; GNU Emacs is distributed in the hope that it will be useful,
  54. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  55. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  56. ;; GNU General Public License for more details.
  57.  
  58. ;; You should have received a copy of the GNU General Public License
  59. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  60. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  61.  
  62. ;; Some suggestions for your .emacs file:
  63. ;;
  64. ;; (autoload 'sgml-mode "sgml-mode" "SGML mode" t)
  65. ;;
  66. ;; (setq auto-mode-alist
  67. ;;       (append (list (cons "\\.sgm$" 'sgml-mode)
  68. ;;                     (cons "\\.sgml$"  'sgml-mode)
  69. ;;                     (cons "\\.dtd$" 'sgml-mode))
  70. ;;               auto-mode-alist))
  71.  
  72. (provide 'sgml-mode)
  73. (require 'compile)
  74.  
  75. ;;; sgmls is a free SGML parser available from
  76. ;;; ftp.uu.net:pub/text-processing/sgml
  77. ;;; Its error messages can be parsed by next-error.
  78. ;;; The -s option suppresses output.
  79.  
  80. (defconst sgml-validate-command
  81.   "sgmls -s"
  82.   "*The command to validate an SGML document.
  83. The file name of current buffer file name will be appended to this,
  84. separated by a space.")
  85.  
  86. (defvar sgml-saved-validate-command nil
  87.   "The command last used to validate in this buffer.")
  88.  
  89. (defvar sgml-mode-map nil "Keymap for SGML mode")
  90.  
  91. (if sgml-mode-map
  92.     ()
  93.   (setq sgml-mode-map (make-sparse-keymap))
  94.   (define-key sgml-mode-map ">" 'sgml-close-angle)
  95.   (define-key sgml-mode-map "/" 'sgml-slash)
  96.   (define-key sgml-mode-map "\C-c\C-v" 'sgml-validate))
  97.  
  98. (defun sgml-mode ()
  99.   "Major mode for editing SGML.
  100. Makes > display the matching <.  Makes / display matching /.
  101. Use \\[sgml-validate] to validate your document with an SGML parser."
  102.   (interactive)
  103.   (kill-all-local-variables)
  104.   (setq local-abbrev-table text-mode-abbrev-table)
  105.   (use-local-map sgml-mode-map)
  106.   (setq mode-name "SGML")
  107.   (setq major-mode 'sgml-mode)
  108.   (make-local-variable 'paragraph-start)
  109.   ;; A start or end tag by itself on a line separates a paragraph.
  110.   ;; This is desirable because SGML discards a newline that appears
  111.   ;; immediately after a start tag or immediately before an end tag.
  112.   (setq paragraph-start
  113.     "^[ \t\n]\\|\
  114. \\(</?\\([A-Za-z]\\([-.A-Za-z0-9= \t\n]\\|\"[^\"]*\"\\|'[^']*'\\)*\\)?>$\\)")
  115.   (make-local-variable 'paragraph-separate)
  116.   (setq paragraph-separate
  117.     "^[ \t\n]*$\\|\
  118. ^</?\\([A-Za-z]\\([-.A-Za-z0-9= \t\n]\\|\"[^\"]*\"\\|'[^']*'\\)*\\)?>$")
  119.   (make-local-variable 'sgml-saved-validate-command)
  120.   (set-syntax-table text-mode-syntax-table)
  121.   (make-local-variable 'comment-start)
  122.   (setq comment-start "<!-- ")
  123.   (make-local-variable 'comment-end)
  124.   (setq comment-end " -->")
  125.   (make-local-variable 'comment-indent-hook)
  126.   (setq comment-indent-hook 'sgml-comment-indent)
  127.   (make-local-variable 'comment-start-skip)
  128.   ;; This will allow existing comments within declarations to be
  129.   ;; recognized.
  130.   (setq comment-start-skip "--[ \t]*")
  131.   (run-hooks 'text-mode-hook 'sgml-mode-hook))
  132.  
  133. (defun sgml-comment-indent ()
  134.   (if (and (looking-at "--")
  135.        (not (and (eq (char-after (1- (point))) ?!)
  136.              (eq (char-after (- (point) 2)) ?<))))
  137.       (progn
  138.     (skip-chars-backward " \t")
  139.     (max comment-column (1+ (current-column))))
  140.     0))
  141.  
  142. (defconst sgml-start-tag-regex
  143.   "<[A-Za-z]\\([-.A-Za-z0-9= \n\t]\\|\"[^\"]*\"\\|'[^']*'\\)*"
  144.   "Regular expression that matches a non-empty start tag.
  145. Any terminating > or / is not matched.")
  146.  
  147. (defvar sgml-mode-markup-syntax-table nil
  148.   "Syntax table used for scanning SGML markup.")
  149.  
  150. (if sgml-mode-markup-syntax-table
  151.     ()
  152.   (setq sgml-mode-markup-syntax-table (make-syntax-table))
  153.   (modify-syntax-entry ?< "(>" sgml-mode-markup-syntax-table)
  154.   (modify-syntax-entry ?> ")<" sgml-mode-markup-syntax-table)
  155.   (modify-syntax-entry ?- "_ 1234" sgml-mode-markup-syntax-table)
  156.   (modify-syntax-entry ?\' "\"" sgml-mode-markup-syntax-table))
  157.  
  158. (defconst sgml-angle-distance 4000
  159.   "*If non-nil, is the maximum distance to search for matching <
  160. when > is inserted.")
  161.  
  162. (defun sgml-close-angle (arg)
  163.   "Insert > and display matching <."
  164.   (interactive "p")
  165.   (insert-char ?> arg)
  166.   (if (> arg 0)
  167.       (let ((oldpos (point))
  168.         (blinkpos))
  169.     (save-excursion
  170.       (save-restriction
  171.         (if sgml-angle-distance
  172.         (narrow-to-region (max (point-min)
  173.                        (- (point) sgml-angle-distance))
  174.                   oldpos))
  175.         ;; See if it's the end of a marked section.
  176.         (and (> (- (point) (point-min)) 3)
  177.          (eq (char-after (- (point) 2)) ?\])
  178.          (eq (char-after (- (point) 3)) ?\])
  179.          (re-search-backward "<!\\[\\(-?[A-Za-z0-9. \t\n&;]\\|\
  180. --\\([^-]\\|-[^-]\\)*--\\)*\\["
  181.                      (point-min)
  182.                      t)
  183.          (let ((msspos (point)))
  184.            (if (and (search-forward "]]>" oldpos t)
  185.                 (eq (point) oldpos))
  186.                (setq blinkpos msspos))))
  187.         ;; This handles cases where the > ends one of the following:
  188.         ;; markup declaration starting with <! (possibly including a
  189.         ;; declaration subset); start tag; end tag; SGML declaration.
  190.         (if blinkpos
  191.         ()
  192.           (goto-char oldpos)
  193.           (condition-case ()
  194.           (let ((oldtable (syntax-table))
  195.             (parse-sexp-ignore-comments t))
  196.             (unwind-protect
  197.             (progn
  198.               (set-syntax-table sgml-mode-markup-syntax-table)
  199.               (setq blinkpos (scan-sexps oldpos -1)))
  200.               (set-syntax-table oldtable)))
  201.         (error nil))
  202.           (and blinkpos
  203.            (goto-char blinkpos)
  204.            (or
  205.             ;; Check that it's a valid delimiter in context.
  206.             (not (looking-at
  207.               "<\\(\\?\\|/?[A-Za-z>]\\|!\\([[A-Za-z]\\|--\\)\\)"))
  208.             ;; Check that it's not a net-enabling start tag
  209.             ;; nor an unclosed start-tag.
  210.             (looking-at (concat sgml-start-tag-regex "[/<]"))
  211.             ;; Nor an unclosed end-tag.
  212.             (looking-at "</[A-Za-z][-.A-Za-z0-9]*[ \t]*<"))
  213.            (setq blinkpos nil)))
  214.         (if blinkpos
  215.         ()
  216.           ;; See if it's the end of a processing instruction.
  217.           (goto-char oldpos)
  218.           (if (search-backward "<?" (point-min) t)
  219.           (let ((pipos (point)))
  220.             (if (and (search-forward ">" oldpos t)
  221.                  (eq (point) oldpos))
  222.             (setq blinkpos pipos))))))
  223.       (if blinkpos
  224.           (progn
  225.         (goto-char blinkpos)
  226.         (if (pos-visible-in-window-p)
  227.             (sit-for 1)
  228.           (message "Matches %s"
  229.                (buffer-substring blinkpos
  230.                          (progn (end-of-line)
  231.                             (point)))))))))))
  232.  
  233. ;;; I doubt that null end tags are used much for large elements,
  234. ;;; so use a small distance here.
  235. (defconst sgml-slash-distance 1000
  236.   "*If non-nil, is the maximum distance to search for matching /
  237. when / is inserted.")
  238.  
  239. (defun sgml-slash (arg)
  240.   "Insert / and display any previous matching /.
  241. Two /s are treated as matching if the first / ends a net-enabling
  242. start tag, and the second / is the corresponding null end tag."
  243.   (interactive "p")
  244.   (insert-char ?/ arg)
  245.   (if (> arg 0)
  246.       (let ((oldpos (point))
  247.         (blinkpos)
  248.         (level 0))
  249.     (save-excursion
  250.       (save-restriction
  251.         (if sgml-slash-distance
  252.         (narrow-to-region (max (point-min)
  253.                        (- (point) sgml-slash-distance))
  254.                   oldpos))
  255.         (if (and (re-search-backward sgml-start-tag-regex (point-min) t)
  256.              (eq (match-end 0) (1- oldpos)))
  257.         ()
  258.           (goto-char (1- oldpos))
  259.           (while (and (not blinkpos)
  260.               (search-backward "/" (point-min) t))
  261.         (let ((tagend (save-excursion
  262.                 (if (re-search-backward sgml-start-tag-regex
  263.                             (point-min) t)
  264.                     (match-end 0)
  265.                   nil))))
  266.           (if (eq tagend (point))
  267.               (if (eq level 0)
  268.               (setq blinkpos (point))
  269.             (setq level (1- level)))
  270.             (setq level (1+ level)))))))
  271.       (if blinkpos
  272.           (progn
  273.         (goto-char blinkpos)
  274.         (if (pos-visible-in-window-p)
  275.             (sit-for 1)
  276.           (message "Matches %s"
  277.                (buffer-substring (progn
  278.                            (beginning-of-line)
  279.                            (point))
  280.                          (1+ blinkpos))))))))))
  281.  
  282. (defun sgml-validate (command)
  283.   "Validate an SGML document.
  284. Runs COMMAND, a shell command, in a separate process asynchronously
  285. with output going to the buffer *compilation*.
  286. You can then use the command \\[next-error] to find the next error message
  287. and move to the line in the SGML document that caused it."
  288.   (interactive
  289.    (list (read-string "Validate command: "
  290.               (or sgml-saved-validate-command
  291.               (concat sgml-validate-command
  292.                   " "
  293.                   (let ((name (buffer-file-name)))
  294.                     (and name
  295.                      (file-name-nondirectory name))))))))
  296.   (setq sgml-saved-validate-command command)
  297.   (compile1 command "No more errors"))
  298.  
  299. --cut-here
  300. Content-Type: message/external-body;
  301.         ACCESS-TYPE=ANON-FTP;
  302.         NAME="sgmls-0.8.tar";
  303.         SITE="ifi.uio.no";
  304.         DIRECTORY="/pub/SGML/SGMLS";
  305.         SIZE=1116160;
  306.         PERMISSION=read-write
  307.  
  308. Content-Type: application/octet-stream;
  309.         type=tar;
  310.         name="sgmls-0.8.tar"
  311. X-Last-Modified: 19920514010000Z (1992 May 14 01:00:00 GMT)
  312.  
  313. ifi.uio.no:/pub/SGML/SGMLS/sgmls-0.8.tar
  314. file://ifi.uio.no/pub/SGML/SGMLS/sgmls-0.8.tar
  315. -r--r--r--  1 ftp 1116160 1992 May 14 01:00:00 GMT sgmls-0.8.tar
  316.  
  317.  
  318. --cut-here--
  319.